package com.jh.user.pojo;

import com.alibaba.fastjson.JSON;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Maps;
import com.google.common.collect.Range;
import com.jh.user.controller.model.RangeRateModel;
import com.jh.user.controller.model.ThirdPayRateRequest;
import com.jh.user.pojo.enums.ThirdPayType;
import com.jh.user.pojo.freeQuick.AbstractRecording;

import javax.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author Yichuan
 * @version 1.0
 */
@Entity
@Table(name="t_third_pay_rate")
public class ThirdPayRate extends AbstractRecording<Long> {

    private static final long serialVersionUID = 7413789806913825656L;

    public static ThirdPayRate init(ThirdPayRateRequest thirdRequest) {
        ThirdPayRate thirdPayRate = new ThirdPayRate();
        thirdPayRate.setBrandId(thirdRequest.getBrandId());
        thirdPayRate.setType(thirdRequest.getPayType());
        LocalDateTime now = LocalDateTime.now();
        thirdPayRate.setUpdatedAt(now);
        thirdPayRate.setCreatedAt(now);
        return thirdPayRate;
    }

    // 贴牌id
    @Column(name = "brand_id")
    private Long brandId;

    // 类型
    @Enumerated(EnumType.STRING)
    @Column(name = "type")
    private ThirdPayType type;

    // 设置内容
    @Column(name = "setting")
    private String setting;

    @Transient
    private List<RangeRateModel> rangeList;
    @Transient
    private Map<Range<BigDecimal>, BigDecimal> rangeData;

    public ThirdPayRate() {
        super();
    }

    public Long getBrandId() {
        return brandId;
    }

    public void setBrandId(Long brandId) {
        this.brandId = brandId;
    }

    public ThirdPayType getType() {
        return type;
    }

    public void setType(ThirdPayType type) {
        this.type = type;
    }

    public String getSetting() {
        return setting;
    }

    public void setSetting(String setting) {
        this.setting = setting;
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public List<RangeRateModel> getRangeList() {
        if (rangeList == null || rangeList.isEmpty()) {
            rangeList = JSON.parseArray(setting, RangeRateModel.class);
        }
        return rangeList;
    }

    public void setRangeList(List<RangeRateModel> rangeList) {
        this.setting = JSON.toJSONString(rangeList);
        this.rangeList = rangeList;
    }

    public Map<Range<BigDecimal>, BigDecimal> getRangeData() {
        if (rangeData == null || rangeData.isEmpty()) {
            if (getRangeList() == null || getRangeList().isEmpty()) {
                return Maps.newHashMap();
            }
            rangeData = Maps.newHashMap();
            for (RangeRateModel model: getRangeList()) {
                Range<BigDecimal> range = model.ofRange();
                if (range == null) continue;
                rangeData.put(range, model.getRate());
            }
        }
        return rangeData;
    }


    public void setRangeData(Map<Range<BigDecimal>, BigDecimal> rangeData) {
        this.rangeData = rangeData;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof ThirdPayRate)) return false;
        ThirdPayRate that = (ThirdPayRate) o;
        return Objects.equals(getId(), that.getId()) &&
                Objects.equals(getBrandId(), that.getBrandId()) &&
                getType() == that.getType() &&
                Objects.equals(getSetting(), that.getSetting()) &&
                Objects.equals(getUpdatedAt(), that.getUpdatedAt()) &&
                Objects.equals(getCreatedAt(), that.getCreatedAt());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId(), getBrandId(), getType(), getSetting(), getUpdatedAt(), getCreatedAt());
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("id", getId())
                .add("brandId", brandId)
                .add("type", type)
                .add("setting", setting)
                .add("updatedAt", getUpdatedAt())
                .add("createdAt", getCreatedAt())
                .toString();
    }

    /**
     * 根据金额获取指定区间的费率
     *
     * @param amount 金额
     * @return 返回费率
     */
    public BigDecimal getPayRate(BigDecimal amount) {
        Map<Range<BigDecimal>, BigDecimal> rangeData = getRangeData();
        for (Map.Entry<Range<BigDecimal>, BigDecimal> entry: rangeData.entrySet()) {
            Range<BigDecimal> key = entry.getKey();
            if (key.contains(amount)) {
                return entry.getValue();
            }
        }
        return null;
    }

    /**
     * 根据金额获取指定区间的费率
     *
     * @param amount 金额
     * @return 返回商户费率，平台费率，代理商费率
     */
    public Map<Object,Object> getPayRateMap(BigDecimal amount) {
        Map<Object,Object> pram = new HashMap<>();
        Map<Range<BigDecimal>, BigDecimal> rangeData = new HashMap<>();
        List<Map<String,Object>> list = new ArrayList<>();
        for (RangeRateModel model: getRangeList()) {
            Map<String,Object> param = rangeMap(model);
            Range<BigDecimal> range = (Range<BigDecimal>) param.get("range");
            rangeData.put(range, model.getAgentRate());
            list.add(param);
        }


        for (Map.Entry<Range<BigDecimal>, BigDecimal> entry: rangeData.entrySet()) {
            Range<BigDecimal> key = entry.getKey();
            if (key.contains(amount)) {
                pram.put("agentRate",entry.getValue());
                break;
            }
        }

        for (RangeRateModel model: getRangeList()) {
            Map<String,Object> param = rangeMap(model);
            Range<BigDecimal> range = (Range<BigDecimal>) param.get("range");
            rangeData.put(range, model.getPlatformRate());
            list.add(param);
        }
        for (Map.Entry<Range<BigDecimal>, BigDecimal> entry: rangeData.entrySet()) {
            Range<BigDecimal> key = entry.getKey();
            if (key.contains(amount)) {
                pram.put("platformRate",entry.getValue());
                break;
            }
        }

        return pram;
    }

    /**
     * 查询返回集合
     */
    public Map<String,Object> rangeMap(RangeRateModel rangeRateModel) {
        Map<String, Object> pram = new HashMap<>();
        Range<BigDecimal> range = rangeRateModel.ofRange();
        if (rangeRateModel.getPlatformRate() != null) {
            pram.put("platformRate", rangeRateModel.getPlatformRate());
        } else {
            pram.put("platformRate","0.0000");
        }
        if (rangeRateModel.getRate() != null) {
            pram.put("rate", rangeRateModel.getRate());
        } else {
            pram.put("rate","0.0000");
        }

        pram.put("range",range);
        pram.put("agentRate",rangeRateModel.getAgentRate());
        return pram;

    }

    public Map<Range<BigDecimal>, BigDecimal> getRange() {
        if (rangeData == null || rangeData.isEmpty()) {
            if (getRangeList() == null || getRangeList().isEmpty()) {
                return Maps.newHashMap();
            }
            rangeData = Maps.newHashMap();
            for (RangeRateModel model: getRangeList()) {
                Range<BigDecimal> range = model.ofRange();
                if (range == null) continue;
                rangeData.put(range, model.getAgentRate());
            }
        }
        return rangeData;
    }

}
